package dao

import (
	"context"
	"gitee.com/chunanyong/zorm"
	"gitee.com/xinshortlink/internal/constants"
	"gitee.com/xinshortlink/internal/dal/db/model"
	"gitee.com/xinshortlink/internal/dto"
	"gitee.com/xinshortlink/internal/dto/resp/bizerr"
	"go.uber.org/zap"
	"time"
)

type LinkDao struct {
	logger *zap.Logger
}

func NewLinkDao(logger *zap.Logger) *LinkDao {
	return &LinkDao{logger: logger}
}

func (dao *LinkDao) Create(ctx context.Context, link *model.LinkStruct) error {
	_, err := zorm.Insert(ctx, link)
	if err != nil {
		return bizerr.New(bizerr.DB, "创建短链接出错", err)
	}
	return nil
}

func (dao *LinkDao) CreateBatch(ctx context.Context, links []zorm.IEntityStruct) error {
	_, err := zorm.InsertSlice(ctx, links)
	if err != nil {
		return bizerr.New(bizerr.DB, "创建短链接出错", err)
	}
	return nil
}

func (dao *LinkDao) Del(ctx context.Context, id int64, gid int64) error {
	link := &model.LinkStruct{
		Id:       id,
		Gid:      gid,
		DelTime:  time.Now(),
		DelState: constants.YES,
	}
	_, err := zorm.UpdateNotZeroValue(ctx, link)

	if err != nil {
		return bizerr.New(bizerr.DB, "删除短链接出错", err)
	}

	return nil
}

func (dao *LinkDao) UpdateStatus(ctx context.Context, id int64, gid int64, status int8) error {
	e := &model.LinkStruct{
		Gid: gid,
	}

	// UPDATE tableName SET
	finder := zorm.NewUpdateFinder(e.GetTableName()).Append("enable_status = ? WHERE id = ?", status, id)
	_, err := zorm.UpdateFinder(ctx, finder)

	if err != nil {
		return bizerr.New(bizerr.DB, "更新短链接状态出错", err)
	}

	return nil
}

func (dao *LinkDao) FindLinks(ctx context.Context, req *dto.FindLinkDTO) (*zorm.Page, []*model.LinkStruct, error) {
	page := zorm.NewPage()
	page.PageNo = req.PageNo
	page.PageSize = req.PageSize

	e := &model.LinkStruct{
		Gid: req.Gid,
	}

	finder := zorm.NewSelectFinder(e.GetTableName()).Append("WHERE gid = ? AND del_state = ?", req.Gid, constants.NO)

	if req.OriginUrl != "" {
		finder.Append("AND origin_url LIKE ?", req.OriginUrl+"%") // 原始链接反向存储；可以使用前缀模糊查询；使用索引
	}

	list := make([]*model.LinkStruct, 0)

	err := zorm.Query(ctx, finder, &list, page)

	if err != nil {
		return nil, nil, bizerr.New(bizerr.DB, "查询短链接出错", err)
	}

	return page, list, nil
}

func (dao *LinkDao) FindLinkById(ctx context.Context, id int64, gid int64) (*model.LinkStruct, error) {
	e := &model.LinkStruct{
		Gid: gid,
	}

	finder := zorm.NewSelectFinder(e.GetTableName()).Append("WHERE id = ?", id)

	l := &model.LinkStruct{}

	has, err := zorm.QueryRow(ctx, finder, l)
	if err != nil {
		return nil, bizerr.New(bizerr.DB, "查询短链接出错", err)
	}

	if !has {
		return nil, nil
	}

	return l, nil
}

func (dao *LinkDao) FindLinkByShortId(ctx context.Context, shortId string, gid int64) (*model.LinkStruct, error) {
	e := &model.LinkStruct{
		Gid: gid,
	}

	finder := zorm.NewSelectFinder(e.GetTableName()).Append("WHERE short_id = ?", shortId)

	l := &model.LinkStruct{}

	has, err := zorm.QueryRow(ctx, finder, l)
	if err != nil {
		return nil, bizerr.New(bizerr.DB, "查询短链接出错", err)
	}

	if !has {
		return nil, nil
	}

	return l, nil
}

func (dao *LinkDao) FindLinkCountByShortId(ctx context.Context, shortId string, gid int64) (int, error) {
	e := &model.LinkStruct{
		Gid: gid,
	}

	finder := zorm.NewSelectFinder(e.GetTableName(), "count(id)").Append("WHERE short_id = ?", shortId)

	count := 0

	has, err := zorm.QueryRow(ctx, finder, &count)
	if err != nil {
		return 0, bizerr.New(bizerr.DB, "查询短链接出错", err)
	}

	if !has {
		return 0, nil
	}

	return count, nil
}

func (dao *LinkDao) UpdateClickNum(ctx context.Context, shortId string, gid int64, count int) error {
	e := &model.LinkStruct{
		Gid: gid,
	}

	finder := zorm.NewUpdateFinder(e.GetTableName()).Append("click_num = click_num + ? , update_time = ? WHERE short_id = ?", count, time.Now(), shortId)
	_, err := zorm.UpdateFinder(ctx, finder)
	if err != nil {
		return bizerr.New(bizerr.DB, "更新短链接点击量出错", err)
	}

	return nil
}
